package com.salt.modules.log.service.impl;

import com.salt.modules.log.dao.LoginRecordDao;
import com.salt.modules.log.dao.OperationRecordDao;
import com.salt.modules.log.domain.LoginLog;
import com.salt.modules.log.domain.OperationLog;
import com.salt.modules.log.model.data.LoginRecord;
import com.salt.modules.log.model.data.OperationRecord;
import com.salt.modules.log.model.query.RecordQuery;
import com.salt.modules.log.service.LogService;
import com.salt.modules.log.utils.SnowflakeUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description
 * @Author salt
 * @Date 2023/4/19
 * @Version 1.0.1
 */
@Service
public class LogServiceImpl implements LogService {

    @Autowired
    private OperationRecordDao operationRecordDao;
    @Autowired
    private LoginRecordDao loginRecordDao;

    @Override
    public void save(OperationLog operationLog) {
        OperationRecord operationRecord = new OperationRecord();
        BeanUtils.copyProperties(operationLog, operationRecord);
        operationRecord.setModuleName(operationLog.getModule());
        operationRecord.setId(SnowflakeUtil.nextId());
        operationRecordDao.save(operationRecord);
    }

    @Override
    public void save(LoginLog loginLog) {
        LoginRecord loginRecord = new LoginRecord();
        BeanUtils.copyProperties(loginLog, loginRecord);
        loginRecord.setId(SnowflakeUtil.nextId());
        loginRecordDao.save(loginRecord);
    }

    @Override
    public Map<String, Object> operationRecordPage(Integer pageNum, Integer pageSize, RecordQuery recordQuery) {
        Pageable pageable = PageRequest.of(pageNum-1, pageSize, Sort.by(Sort.Order.desc("operTime")));
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        if (StringUtils.isNotBlank(recordQuery.getService())) {
            MatchQueryBuilder serviceQueryBuilder = new MatchQueryBuilder(
                    "service", recordQuery.getService());
            queryBuilder.must(serviceQueryBuilder);
        }
        if (StringUtils.isNotBlank(recordQuery.getModuleName())) {
            MatchQueryBuilder moduleQueryBuilder = new MatchQueryBuilder(
                    "moduleName", recordQuery.getModuleName());
            queryBuilder.must(moduleQueryBuilder);
        }
        if (StringUtils.isNotBlank(recordQuery.getOperRealName())) {
            MatchQueryBuilder moduleQueryBuilder = new MatchQueryBuilder(
                    "operRealName", recordQuery.getOperRealName());
            queryBuilder.must(moduleQueryBuilder);
        }
        if (StringUtils.isNotBlank(recordQuery.getUserName())) {
            MatchQueryBuilder moduleQueryBuilder = new MatchQueryBuilder(
                    "userName", recordQuery.getUserName());
            queryBuilder.must(moduleQueryBuilder);
        }
        if (StringUtils.isNotBlank(recordQuery.getStartOperTime()) && StringUtils.isNotBlank(recordQuery.getEndOperTime())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("operTime")
                    .gte(recordQuery.getStartOperTime())
                    .lte(recordQuery.getEndOperTime());
            queryBuilder.filter(rangeQueryBuilder);
        }
        Page<OperationRecord> search = operationRecordDao.search(queryBuilder, pageable);
        Map<String, Object> page = new HashMap<>();
        page.put("pageNo", search.getNumber());
        page.put("pageSize", search.getSize());
        page.put("count", search.getTotalElements());
        page.put("content", search.getContent());
        page.put("totalPages", search.getTotalPages());
        return page;
    }

    @Override
    public Map<String, Object> loginRecordPage(Integer pageNum, Integer pageSize, RecordQuery recordQuery) {
        Pageable pageable = PageRequest.of(pageNum-1, pageSize, Sort.by(Sort.Order.desc("accessTime")));
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        if (StringUtils.isNotBlank(recordQuery.getStartOperTime()) && StringUtils.isNotBlank(recordQuery.getEndOperTime())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("accessTime")
                    .gte(recordQuery.getStartOperTime())
                    .lte(recordQuery.getEndOperTime());
            queryBuilder.filter(rangeQueryBuilder);
        }
        if (StringUtils.isNotBlank(recordQuery.getUserName())) {
            MatchQueryBuilder moduleQueryBuilder = new MatchQueryBuilder(
                    "userName", recordQuery.getUserName());
            queryBuilder.must(moduleQueryBuilder);
        }
        if (StringUtils.isNotBlank(recordQuery.getOperRealName())) {
            MatchQueryBuilder moduleQueryBuilder = new MatchQueryBuilder(
                    "operRealName", recordQuery.getOperRealName());
            queryBuilder.must(moduleQueryBuilder);
        }
        Page<LoginRecord> search = loginRecordDao.search(queryBuilder, pageable);
        Map<String, Object> page = new HashMap<>();
        page.put("pageNo", search.getNumber());
        page.put("pageSize", search.getSize());
        page.put("count", search.getTotalElements());
        page.put("content", search.getContent());
        page.put("totalPages", search.getTotalPages());
        return page;
    }
}
